﻿//
// (C) Copyright 2009 Irantha Suwandarathna (iranthas@hotmail.com)
// All rights reserved.
//

/* Copyright (c) 2001-2008, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use _in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions _in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer _in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EffiProz.Core.Lib;
using EffiProz.Core.Persist;
using EffiProz.Core.Rights;
using EffiProz.Core.Errors;
using EffiProz.Core.DataTypes;
using EffiProz.Core.Navigators;

namespace EffiProz.Core.Indexes
{
    public interface Index : SchemaObject
    {
     
        RowIterator emptyIterator();

        int getPosition();

        void setPosition(int position);
        long getPersistenceId();

        /**
         * Returns the count of visible columns used
         */
        int getVisibleColumns();

        int getColumnCount();

        /**
         * Is this a UNIQUE index?
         */
        bool isUnique();

        /**
         * Does this index belong to a constraint?
         */
        bool isConstraint();

        /**
         * Returns the array containing column indexes for index
         */
        int[] getColumns();

        /**
         * Returns the array containing column indexes for index
         */
        SqlType[] getColumnTypes();

        /**
         * Returns the count of visible columns used
         */
        bool[] getColumnDesc();

        /**
         * Returns a value indicating the order of different types of index in
         * the list of indexes for a table. The position of the groups of Indexes
         * in the list in ascending order is as follows:
         *
         * primary key index
         * unique constraint indexes
         * autogenerated foreign key indexes for FK's that reference this table or
         *  tables created before this table
         * user created indexes (CREATE INDEX)
         * autogenerated foreign key indexes for FK's that reference tables created
         *  after this table
         *
         * Among a group of indexes, the order is based on the order of creation
         * of the index.
         *
         * @return ordinal value
         */
        int getIndexOrderValue();

        bool isForward();

        /**
         * Returns the node count.
         */
        int size(PersistentStore store);

        int sizeEstimate(PersistentStore store);

        bool isEmpty(PersistentStore store);

        void checkIndex(PersistentStore store);

        /**
         * Insert a node into the index
         */
        void insert(Session session, PersistentStore store, Row row);

        void delete(PersistentStore store, Row row);

        bool exists(Session session, PersistentStore store,
                              Object[] rowdata, int[] rowColMap);

        /**
         * Return the first node equal to the indexdata object. The rowdata has
         * the same column mapping as this index.
         *
         * @param session session object
         * @param store store object
         * @param coldata array containing index column data
         * @param match count of columns to match
         * @return iterator
         */
        RowIterator findFirstRow(Session session, PersistentStore store,
                                        Object[] rowdata, int match);

        /**
         * Return the first node equal to the rowdata object.
         * The rowdata has the same column mapping as this table.
         *
         * @param session session object
         * @param store store object
         * @param rowdata array containing table row data
         * @return iterator
         */
        RowIterator findFirstRow(Session session, PersistentStore store,
                                        Object[] rowdata);

        /**
         * Return the first node equal to the rowdata object.
         * The rowdata has the column mapping privided in rowColMap.
         *
         * @param session session object
         * @param store store object
         * @param rowdata array containing table row data
         * @return iterator
         */
        RowIterator findFirstRow(Session session, PersistentStore store,
                                        Object[] rowdata, int[] rowColMap);

        /**
         * Finds the first node that is larger or equal to the given one based
         * on the first column of the index only.
         *
         * @param session session object
         * @param store store object
         * @param value value to match
         * @param compare comparison Expression type
         *
         * @return iterator
         * 
         */
         
        RowIterator findFirstRow(Session session, PersistentStore store,
                                        Object value, int compare);

        /**
         * Finds the first node where the data is not null.
         *
         * @return iterator
         */
        RowIterator findFirstRowNotNull(Session session,
                                               PersistentStore store);

        RowIterator firstRow(PersistentStore store);

        /**
         * Returns the row for the first node of the index
         *
         * @return Iterator for first row
         */
        RowIterator firstRow(Session session, PersistentStore store);

        /**
         * Returns the row for the last node of the index
         *
         * @return last row
         */
        Row lastRow(Session session, PersistentStore store);

        /**
         * Compares two table rows based on the columns of this index. The rowColMap
         * parameter specifies which columns of the other table are to be compared
         * with the colIndex columns of this index. The rowColMap can cover all
         * or only some columns of this index.
         *
         * @param a row from another table
         * @param rowColMap column indexes in the other table
         * @param b a full row in this table
         *
         * @return comparison result, -1,0,+1
         */
        int compareRowNonUnique(Session session, Object[] a,
                                       int[] rowColMap, Object[] b);

        int compareRowNonUnique(Session session, Object[] a,
                                       int[] rowColMap, Object[] b,
                                       int fieldCount);

        /**
         * As above but use the index column data
         */
        int compareRowNonUnique(Session session, Object[] a, Object[] b,
                                       int fieldcount);
    }
}
